<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2019/11/25
 * Time: 17:09
 */

namespace app\api\controller;

use app\api\tools\ToolsClass;
use app\common\controller\Api;
use think\Db;
use fast\Random;
use think\Config;
use app\common\library\Token;
use think\Exception;
/*
 *微信登录类接口
 */
class Wxoperator extends Api
{
    protected $noNeedLogin = ['*'];
    protected $noNeedRight = ['*'];
    public function _initialize()
    {
        parent::_initialize(); // TODO: Change the autogenerated stub
    }
    /**
     * 登录和注册接口
     *
     * @ApiTitle    (登录和注册)
     * @ApiSummary  (小程序用户登录和注册到本平台)
     * @ApiMethod   (POST)
     * @ApiRoute    (/api/Wxoperator/wxLogin)
     * @ApiParams   (name="code", type="string", required=true, description="小程序登录凭证")
     * @ApiParams   (name="rawData", type="string", required=false, description="rawData")
     * @ApiParams   (name="signature", type="string", required=false, description="signature")
     * @ApiParams   (name="encryptedData", type="string", required=false, description="encryptedData")
     * @ApiParams   (name="iv", type="string", required=false, description="iv")
     * @ApiReturnParams   (name="code", type="integer", required=true, sample="1000")
     * @ApiReturnParams   (name="msg", type="string", required=true, sample="登录成功")
     * @ApiReturnParams   (name="data.resource", type="object", sample="{'userId':'int','token':'string'}", description="1 群聊 2朋友圈 3单聊 4搜索")
     * @ApiReturn   ({
    'code':1000,
    'msg':'登录成功',
    'time':'1566976963',
    'data':"{
    'userId':'1',
    'token':'dabdwdhwadhajh1232',
    }",
    })
     */
    public function wxLogin(){
        $js_code = $this->request->request('code');
        if (!$js_code){
            $this->error('code不能为空');
        }
        $url = "https://api.weixin.qq.com/sns/jscode2session";
        try {
            Db::startTrans();
            // 参数
            $wxParams['appid'] = constant('APP_ID');
            $wxParams['secret'] = constant('APP_SECRET');
            $wxParams['grant_type'] = 'authorization_code';
            $wxParams['js_code'] = $js_code;

            // 微信API返回的session_key 和 openid
            $arr = json_decode(ToolsClass::httpWurl($url, $wxParams), true);
            $openid = $arr['openid'];
            $session_key = $arr['session_key'];
            $id = Db::name('user')->where('openid',$openid)->value('id');
            $config = \think\Config::get('token');
            $rawData = $this->request->request('rawData');
            if($id){  //已有账号登录
                $token = Random::uuid();
                $isSuccess = Token::set($token, $id, Config::get('token.keepTime'));
                if($isSuccess){
                    $token =  hash_hmac($config['hashalgo'], $token, $config['key']);
                    $newData['logintime'] =time();
                    Db::name("user")->where("id",$id)->update($newData);
                    Db::commit();
                    $this->success('登录成功', ['token' => $token,'user_id'=>$id]);
                }
            }else{ //注册

                $signature = $this->request->request('signature');
                $encryptedData = $this->request->request('encryptedData');
                $iv = $this->request->request('iv');
                $signature2 = sha1(htmlspecialchars_decode($rawData) . $session_key);
                if ($signature2 !== $signature){
                    $this->error('非法操作：rawData不正确');
                }

                $result = ToolsClass::checkEncryptedData($wxParams['appid'],$openid,$session_key,$iv,$encryptedData);
                if (is_int($result)){
                    $this->error('非法操作：encryptedData不正确');
                }

                $id = Db::name("user")->insert($result);
                $token = Random::uuid();
                Token::set($token, $id, Config::get('token.keepTime'));

                $token =  hash_hmac($config['hashalgo'], $token, $config['key']);
                Db::commit();
                $this->success('注册成功', ['token' => $token,'user_id'=>$id]);
            }
        }catch (Exception $exception){
            Db::rollback();
            $this->error($exception->getMessage(),'');
        }
    }


}